

 
#ifndef ___CAMERA_H___
#define ___CAMERA_H___

#include <cstdint>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <thread>
 
#include <sys/select.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>

#include "semaphore.h"
#include "thread.h"
#include "message_queue.h"


#define FMT_NUM_PLANES 1
 
enum io_method {
        IO_METHOD_READ,
        IO_METHOD_MMAP,
        IO_METHOD_USERPTR,
};
 
struct buffer {
        void   *start;
        size_t  length;
};
 
class Camera : public threadBase{
private:
    const char          *dev_name;
    const char          *capturfile_name;
    enum io_method      io;
    int                 fd;
    struct buffer       *buffers;
    unsigned int        n_buffers;
    int                 out_buf;
    int32_t             frame_count;
    void                *cur_data_start;
    int                 cur_data_len;
    Semaphore           frame_sem;
    MessageQueue<struct buffer> mq;
    int                 mq_max_len;
    struct buffer       *mq_buffers;


    int cam_open(void);
    int cam_close(void);
    int init_device(void);
    int init_mmap(void);
    int uninit_device(void);
    int start_capturing(void);
    int stop_capturing(void);
    bool threadLoop();
    int read_frame(void);
    void process_image(const void *data, int size);
    int store_image(const void *data, int size);
public:
    int                 width;
    int                 height;
    int                 format;
    int read_frame(char*, int, int &);
    int register_push_stream_callback(int (*pfun)(void *data, int size));
    int capture_image(const char *path);
    Camera(const char *device, int width, int height, int fmt);
    ~Camera();
};
#endif /* ___CAMERA_H___ */